package com.pku.smart.trade.channel.wechatpay;

import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.request.*;
import com.github.binarywang.wxpay.bean.result.*;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.pku.smart.log.MyLog;

public class WechatPayUtils {

    private static final MyLog _log = MyLog.getLog(WechatPayUtils.class);

    /**
     * 付款码支付 URL地址：https://api.mch.weixin.qq.com/pay/micropay
     *
     * @param wxPayService
     * @param outTradeNo     商户订单号 要求32个字符内，只能是数字、大小写字母_-|*且在同一个商户号下唯一
     * @param body           商品描述
     * @param totalFee       订单金额 单位为分，只能为整数
     * @param spbillCreateIp 终端IP 支持IPV4和IPV6两种格式的IP地址。调用微信支付API的机器IP
     * @param authCode       付款码 扫码支付付款码，（注：用户付款码条形码规则：18位纯数字，以10、11、12、13、14、15开头）
     * @param attach         附加数据，在查询API和支付通知中原样返回，该字段主要用于商户携带订单的自定义数据
     * @return
     */
    public static JSONObject payMicropay(WxPayService wxPayService, String outTradeNo, String body, String detail, Integer totalFee, String spbillCreateIp, String authCode, String attach) throws WxPayException {
        WxPayMicropayRequest request = new WxPayMicropayRequest();
        request.setOutTradeNo(outTradeNo);
        request.setBody(body);
        request.setDetail(detail);
        request.setTotalFee(totalFee);
        //request.setFeeType(feeType); 货币类型 默认人民币：CNY
        request.setSpbillCreateIp(spbillCreateIp);
        request.setAuthCode(authCode);
        request.setAttach(attach);

        _log.info("============微信条码支付开始============");
        WxPayMicropayResult response = wxPayService.micropay(request);//系统自动判断了return_code 和 result_code如果失败直接抛的异常
        JSONObject responseJSON = JSONObject.parseObject(JSONObject.toJSONString(response));
        _log.info("微信返回结果:{}", responseJSON);
        return responseJSON;
    }

    /**
     * 统一下单 URL地址：https://api.mch.weixin.qq.com/pay/unifiedorder
     *
     * @param wxPayService
     * @param deviceInfo     设备号 自定义参数，可以为终端设备号(门店号或收银设备ID)，PC网页或公众号内支付可以传"WEB"
     * @param body           商品描述
     * @param detail         商品详情 非必填
     * @param attach         附加数据
     * @param outTradeNo     商户订单号
     * @param totalFee       标价金额
     * @param spBillCreateIP 终端IP
     * @param notifyUrl      通知地址
     * @param tradeType      交易类型 JSAPI -JSAPI支付 NATIVE -Native支付  APP -APP支付
     * @param productId      商品ID
     * @param openId         用户标识 trade_type=JSAPI时（即JSAPI支付），此参数必传
     * @return
     */
    public static JSONObject payUnifiedOrder(WxPayService wxPayService, String deviceInfo, String body, String detail, String attach, String outTradeNo, Integer totalFee, String spBillCreateIP, String notifyUrl, String tradeType, String productId, String openId) throws WxPayException {
        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
        request.setDeviceInfo(deviceInfo);
        request.setBody(body);
        request.setDetail(detail);
        request.setAttach(attach);
        request.setOutTradeNo(outTradeNo);
        //request.setFeeType(feeType); CNY
        request.setTotalFee(totalFee);
        request.setSpbillCreateIp(spBillCreateIP);
        //request.setTimeStart(timeStart);
        //request.setTimeExpire(timeExpire);
        request.setNotifyUrl(wxPayService.getConfig().getNotifyUrl());
        request.setTradeType(tradeType);
        request.setProductId(productId);
        request.setOpenid(openId);

        _log.info("============微信扫码支付开始============");
        WxPayUnifiedOrderResult response = wxPayService.unifiedOrder(request);
        JSONObject responseJSON = JSONObject.parseObject(JSONObject.toJSONString(response));
        _log.info("微信返回结果:{}", responseJSON);
        return responseJSON;
    }

    /**
     * 申请退款 https://api.mch.weixin.qq.com/secapi/pay/refund
     *
     * @param wxPayService  一笔退款失败后重新提交，请不要更换退款单号，请使用原商户退款单号
     * @param transactionId 微信订单号
     * @param outTradeNo    商户订单号 在同一个商户号下唯一。transaction_id、out_trade_no二选一，如果同时存在优先级：transaction_id> out_trade_no
     * @param outRefundNo   商户退款单号 同一退款单号多次请求只退一笔。
     * @param totalFee      订单金额
     * @param refundFee     退款金额
     * @param refundDesc    退款原因
     * @param notifyUrl     退款结果通知 如果参数中传了notify_url，则商户平台上配置的回调地址将不会生效
     * @return
     */
    public static JSONObject payRefund(WxPayService wxPayService, String transactionId, String outTradeNo, String outRefundNo, Integer totalFee, Integer refundFee, String refundDesc, String notifyUrl) throws WxPayException {
        WxPayRefundRequest request = new WxPayRefundRequest();
        request.setTransactionId(transactionId);
        request.setOutTradeNo(outTradeNo);
        request.setOutRefundNo(outRefundNo);
        request.setRefundDesc(refundDesc);
        request.setRefundFee(refundFee);
        request.setTotalFee(totalFee);
        //request.setRefundFeeType("CNY");
        request.setNotifyUrl(notifyUrl);

        _log.info("============微信订单退费开始============");
        WxPayRefundResult response = wxPayService.refund(request);
        JSONObject responseJSON = JSONObject.parseObject(JSONObject.toJSONString(response));
        _log.info("微信返回结果:{}", responseJSON);
        return responseJSON;
    }

    /**
     * 撤销订单 https://api.mch.weixin.qq.com/secapi/pay/reverse
     *
     * @param wxPayService
     * @param transactionId 微信订单号 微信的订单号，建议优先使用
     * @param outTradeNo    商户订单号 商户系统内部的订单号,transaction_id、out_trade_no二选一，如果同时存在优先级：transaction_id> out_trade_no
     * @return
     */
    public static JSONObject payOrderReverse(WxPayService wxPayService, String transactionId, String outTradeNo) throws WxPayException {
        WxPayOrderReverseRequest request = new WxPayOrderReverseRequest();
        request.setTransactionId(transactionId);
        request.setOutTradeNo(outTradeNo);

        _log.info("============微信订单撤销开始============");
        WxPayOrderReverseResult response = wxPayService.reverseOrder(request);
        JSONObject responseJSON = JSONObject.parseObject(JSONObject.toJSONString(response));
        _log.info("微信返回结果:{}", responseJSON);
        return responseJSON;
    }

    /**
     * 查询订单 URL地址：https://api.mch.weixin.qq.com/pay/orderquery
     *
     * @param wxPayService
     * @param transactionId 微信订单号 微信的订单号，建议优先使用
     * @param outTradeNo    商户订单号
     * @return
     */
    public static JSONObject payOrderQuery(WxPayService wxPayService, String transactionId, String outTradeNo) throws WxPayException {
        WxPayOrderQueryRequest request = new WxPayOrderQueryRequest();
        request.setTransactionId(transactionId);
        request.setOutTradeNo(outTradeNo);

        _log.info("============微信订单查询开始============");
        WxPayOrderQueryResult response = wxPayService.queryOrder(request);
        JSONObject responseJSON = JSONObject.parseObject(JSONObject.toJSONString(response));
        _log.info("微信返回结果:{}", responseJSON);
        return responseJSON;
    }

    /**
     * 查询退款 接口链接：https://api.mch.weixin.qq.com/pay/refundquery
     *
     * @param wxPayService  微信订单号查询的优先级是： refund_id > out_refund_no > transaction_id > out_trade_no
     * @param transactionId 微信订单号
     * @param outTradeNo    商户订单号
     * @param outRefundNo   商户退款单号
     * @param refundId      微信退款单号
     * @return
     */
    public static JSONObject refundOrderQuery(WxPayService wxPayService, String transactionId, String outTradeNo, String outRefundNo, String refundId) throws WxPayException {
        WxPayRefundQueryRequest request = new WxPayRefundQueryRequest();
        request.setTransactionId(transactionId);
        request.setOutTradeNo(outTradeNo);
        request.setOutRefundNo(outRefundNo);
        request.setRefundId(refundId);

        _log.info("============微信退款查询开始============");
        WxPayRefundQueryResult response = wxPayService.refundQuery(request);
        JSONObject responseJSON = JSONObject.parseObject(JSONObject.toJSONString(response));
        _log.info("微信返回结果:{}", responseJSON);
        return responseJSON;
    }

    /**
     * 微信对账单下载
     * @param wxPayService
     * @param billType 账单类型
     * @param billDate 账单日期
     * @param deviceInfo 设备号
     * @return
     * @throws WxPayException
     */
    public static WxPayBillResult billOrderDownload(WxPayService wxPayService, String billType, String billDate, String tarType, String deviceInfo) throws WxPayException {
        WxPayDownloadBillRequest request = new WxPayDownloadBillRequest();
        request.setBillType(billType);
        request.setBillDate(billDate);
        request.setTarType(tarType);
        request.setDeviceInfo(deviceInfo);

        _log.info("============微信对账单下载开始============");
        WxPayBillResult response =wxPayService.downloadBill(request);
        JSONObject responseJSON = JSONObject.parseObject(JSONObject.toJSONString(response));
        _log.info("微信返回结果:{}", responseJSON);
        return response;
    }
}
